using System.Collections.Generic;
using FireStarter.Base.BusinessObjectMerger;
using Firestarter.DB.Schema.BO;
using Firestarter.DB.Schema.Test.Logic;
using Habanero.Base;
using NUnit.Framework;

namespace Firestarter.Test.Base.BusinessObjectMerger
{
    [TestFixture]
    public class TestBusinessObjectTreeTraverser : TestBase
    {
        [Test]
        public void Test_TraverseTree()
        {
            //---------------Set up test pack-------------------
            BusinessObjectTreeTraverser traverser = new BusinessObjectTreeTraverser();
            DBDatabase dbDatabase = new DBDatabase();
            List<IBusinessObject> visitedBos = new List<IBusinessObject>();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            traverser.TraverseTree(dbDatabase, visitedBos.Add);
            //---------------Test Result -----------------------
            Assert.AreEqual(0, visitedBos.Count);
        }

        [Test]
        public void Test_TraverseTree_OneLevel()
        {
            //---------------Set up test pack-------------------
            BusinessObjectTreeTraverser traverser = new BusinessObjectTreeTraverser();
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTable = dbDatabase.Tables.CreateBusinessObject();
            List<IBusinessObject> visitedBos = new List<IBusinessObject>();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            traverser.TraverseTree(dbDatabase, visitedBos.Add);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, visitedBos.Count);
            Assert.AreSame(dbTable, visitedBos[0]);
        }

        [Test]
        public void Test_TraverseTree_TwoLevels()
        {
            //---------------Set up test pack-------------------
            BusinessObjectTreeTraverser traverser = new BusinessObjectTreeTraverser();
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTableInfo1 = dbDatabase.Tables.CreateBusinessObject();
            DBColumn dbColumnInfo1 = dbTableInfo1.Columns.CreateBusinessObject();
            DBTable dbTableInfo2 = dbDatabase.Tables.CreateBusinessObject();
            DBColumn dbColumnInfo2 = dbTableInfo2.Columns.CreateBusinessObject();
            List<IBusinessObject> visitedBos = new List<IBusinessObject>();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            traverser.TraverseTree(dbDatabase, visitedBos.Add);
            //---------------Test Result -----------------------
            Assert.AreEqual(4, visitedBos.Count);
            Assert.AreSame(dbTableInfo1, visitedBos[0]);
            Assert.AreSame(dbColumnInfo1, visitedBos[1]);
            Assert.AreSame(dbTableInfo2, visitedBos[2]);
            Assert.AreSame(dbColumnInfo2, visitedBos[3]);
        }

        [Test]
        public void Test_TraverseTree_TwoLevels_WithSingle()
        {
            //---------------Set up test pack-------------------
            BusinessObjectTreeTraverser traverser = new BusinessObjectTreeTraverser();
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTableInfo1 = dbDatabase.Tables.CreateBusinessObject();
            DBColumn dbColumnInfo1 = dbTableInfo1.Columns.CreateBusinessObject();
            dbTableInfo1.PrimaryKeyDB = new DBPrimaryKey();
            DBPrimaryKeyColumn dbPrimaryKeyColumn = dbTableInfo1.PrimaryKeyDB.AddColumnInfo(dbColumnInfo1);
            DBTable dbTableInfo2 = dbDatabase.Tables.CreateBusinessObject();
            DBColumn dbColumnInfo2 = dbTableInfo2.Columns.CreateBusinessObject();
            List<IBusinessObject> visitedBos = new List<IBusinessObject>();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            traverser.TraverseTree(dbDatabase, visitedBos.Add);
            //---------------Test Result -----------------------
            Assert.AreEqual(6, visitedBos.Count);
            Assert.AreSame(dbTableInfo1, visitedBos[0]);
            Assert.AreSame(dbColumnInfo1, visitedBos[1]);
            Assert.AreSame(dbTableInfo1.PrimaryKeyDB, visitedBos[2]);
            Assert.AreSame(dbPrimaryKeyColumn, visitedBos[3]);
            Assert.AreSame(dbTableInfo2, visitedBos[4]);
            Assert.AreSame(dbColumnInfo2, visitedBos[5]);
        }

        [Test]
        public void Test_TraverseTree_WithLimit_TwoLevels_WithSingle()
        {
            //---------------Set up test pack-------------------
            BusinessObjectTreeTraverser traverser = new BusinessObjectTreeTraverser();
            DBDatabase dbDatabase = new DBDatabase();
            DBTable dbTableInfo1 = dbDatabase.Tables.CreateBusinessObject();
            DBColumn dbColumnInfo1 = dbTableInfo1.Columns.CreateBusinessObject();
            dbTableInfo1.PrimaryKeyDB = new DBPrimaryKey();
            dbTableInfo1.PrimaryKeyDB.AddColumnInfo(dbColumnInfo1);
            DBTable dbTableInfo2 = dbDatabase.Tables.CreateBusinessObject();
            dbTableInfo2.Columns.CreateBusinessObject();
            List<IBusinessObject> visitedBos = new List<IBusinessObject>();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            traverser.TraverseTree(dbDatabase, 1, visitedBos.Add);
            //---------------Test Result -----------------------
            Assert.AreEqual(2, visitedBos.Count);
            Assert.AreSame(dbTableInfo1, visitedBos[0]);
            Assert.AreSame(dbTableInfo2, visitedBos[1]);
        }
    }
}